package com.wgo.bpot.domain.common.impl;

import java.util.HashSet;
import java.util.Set;

import com.wgo.bpot.domain.common.ServicePrivilege;
import com.wgo.bpot.domain.common.ServicePrivilegeCollection;
import com.wgo.bpot.domain.common.UserRole;

public class UserRoleImpl implements UserRole {
	private String name;
	private Set<UserRole> nestedUserRoles = new HashSet<UserRole>();
    private ServicePrivilegeCollection servicePrivileges = new ServicePrivilegeCollection();
    
	public UserRoleImpl() {
	}
	
	
	public UserRoleImpl(String name, ServicePrivilege... servicePrivileges) {
		this.name = name;
		if (null != servicePrivileges) {
			for (ServicePrivilege servicePrivilege : servicePrivileges) {
                addServicePrivilege(servicePrivilege);
			}
		}
	}

	public Set<UserRole> getNestedUserRoles() {
		return nestedUserRoles;
	}

	public void setNestedUserRoles(Set<UserRole> nestedUserRoles) {
		this.nestedUserRoles = nestedUserRoles;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

    public boolean isAllowed(ServicePrivilege... servicePrivileges){
        return this.servicePrivileges.isAllowed(servicePrivileges);
    }
//    /**
//     * This will return true unless the service privileges are applicable AND not allowed
//     * @return
//     */
//	public <T> boolean isAllowedIfApplicable(Service service, CrudOperation operation, Class<T> conceptType, T conceptInstance) {
//        boolean isOk = servicePrivileges.isAllowedIfApplicable(service, operation, conceptType, conceptInstance);
//		if (isOk) {
//			for (UserRole nestedUserRole : nestedUserRoles) {
//                isOk = nestedUserRole.isAllowedIfApplicable(service, operation, conceptType, conceptInstance);
//                if (!isOk) {
//                    return false;
//                }
//			}
//		}
//		return isOk;
//	}

	public void addNestedUserRole(UserRole userRole) {
		nestedUserRoles.add(userRole);
	}

	public void removeNestedUserRole(UserRole userRole) {
		nestedUserRoles.remove(userRole);
	}


    public void addServicePrivilege(ServicePrivilege servicePrivilege) {
        servicePrivileges.add(servicePrivilege);
    }


    public void removeServicePrivilege(ServicePrivilege servicePrivilege) {
        servicePrivileges.remove(servicePrivilege);
    }


    @Override
    public String toString() {
        return name;
    }


    @Override
    public int hashCode() {
        final int PRIME = 31;
        int result = 1;
        result = PRIME * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }


    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        final UserRoleImpl other = (UserRoleImpl) obj;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }


    public Set<ServicePrivilege> getServicePriviliges() {
        ServicePrivilegeCollection result = new ServicePrivilegeCollection();
        findAllServicePriviliges(result);
        return result.getServicePrivileges();
    }
    
    private void findAllServicePriviliges(ServicePrivilegeCollection result) {
        result.addAll(servicePrivileges);
        for (UserRole nestedUserRole : nestedUserRoles) {
            ((UserRoleImpl)nestedUserRole).findAllServicePriviliges(result);
        }
    }

}
